package com.example.launch;

import cn.hutool.json.JSONUtil;
import com.example.bean.DeviceConf;
import com.example.bean.DeviceStatus;
import com.example.config.DeviceConfiguration;
import com.example.constant.TopicConst;
import com.example.runnable.CollectRunnable;
import com.example.utils.MqttUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 数据接收
 *
 * @author: Fred
 * @email 453086@qq.com
 * @create: 2024-09-03 09:30
 */
@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    private ThreadPoolTaskExecutor executor;

    @Autowired
    private DeviceConfiguration deviceConfiguration;

    @Override
    public void run(ApplicationArguments args) {

        List<DeviceConf> initialDevices = deviceConfiguration.getInitialDevices();

        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(initialDevices.size());
        for (DeviceConf deviceConf : initialDevices) {

            if (deviceConf.getProtocol() != null) {
                CollectRunnable runnable = new CollectRunnable(deviceConf);
                executor.submit(runnable);
            }

            // 状态监控线程池
            scheduler.scheduleAtFixedRate(() -> {
                boolean isReachable = ping(deviceConf.getIp());
                DeviceStatus deviceStatus = new DeviceStatus(deviceConf.getSecret(), isReachable);

                MqttUtil.mqttTemplate.publishAsync(TopicConst.DEVICE_PING + deviceConf.getSecret(), JSONUtil.toJsonStr(deviceStatus).getBytes(StandardCharsets.UTF_8));
            }, 0, 30, TimeUnit.SECONDS);
        }
    }

    private boolean ping(String ipAddress) {
        try {
            InetAddress address = InetAddress.getByName(ipAddress);
            return address.isReachable(1000);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}